/**************************************************************************
** Yabet is bloging editor tool that supports many blog's formats. It is very usefull for crossposting, allows easily to
** make posts to your blogs.
**
** Copyright (C) 2010 Valery Konchin <eeexception@gmail.com>
**
** This program is free software: you can redistribute it and/or modify
**     it under the terms of the GNU General Public License as published by
**     the Free Software Foundation, either version 3 of the License, or
**     (at your option) any later version.
**
**     This program is distributed in the hope that it will be useful,
**     but WITHOUT ANY WARRANTY; without even the implied warranty of
**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
**     GNU General Public License for more details.
**
**     You should have received a copy of the GNU General Public License
**     along with this program.  If not, see <http://www.gnu.org/licenses/>.
**************************************************************************/

#include "imageshackimageuploader.h"
#include <QNetworkAccessManager>
#include <QFile>
#include <QFileInfo>
#include <QUrl>

const YabetLogHandler* ImageShackImageUploader::log = new YabetLogHandler("ImageShackImageUploader");
const QString ImageShackImageUploader::IMAGESHACK_IMAGE_HOST = "http://imageshack.us/upload_api.php";

ImageShackImageUploader::ImageShackImageUploader()
{
    mimeTypes.insert("png", "png");
    mimeTypes.insert("jpg", "jpeg");
    mimeTypes.insert("jpeg", "jpeg");
    mimeTypes.insert("gif", "gif");
}

QString ImageShackImageUploader::getMimeType(QString fileSuffix) {
    return mimeTypes.value(fileSuffix, fileSuffix);
}

QString ImageShackImageUploader::uploadImage(QString imagePath, QString imageHosting) {
    QNetworkAccessManager* manager = new QNetworkAccessManager();

    connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)));

    log->debugMsg("Uploading file " + imagePath + " to image host " + imageHosting);

    QUrl url(imageHosting);
    QNetworkRequest request(url);

    QString boundary = "MYOWNBOUNDARY";
    QByteArray data = preparePostData(imagePath, boundary);

    request.setHeader(QNetworkRequest::ContentTypeHeader, "multipart/form-data; boundary=" + boundary);
    request.setHeader(QNetworkRequest::ContentLengthHeader, QString::number(data.length()));
    request.setRawHeader("Connection","keep-alive");

    wasErrors = false;

    QNetworkReply* reply = manager->post(request, data);

    connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(slotError(QNetworkReply::NetworkError)));
    if(wasErrors == false) {
        connect(reply, SIGNAL(uploadProgress(qint64,qint64)), this, SIGNAL(uploadProgress(qint64,qint64)));
    }

    loop.exec();

    return resultUrl;
}

QByteArray ImageShackImageUploader::preparePostData(QString filePath, QString boundary) {
    QFile sourceFile(filePath);
    QFileInfo fileInfo(filePath);

    QByteArray fileData;
    QByteArray dataToSend;

    if(sourceFile.open(QFile::ReadOnly)) {
        fileData = sourceFile.readAll();

        sourceFile.close();
    }
    else {
        log->warningMsg("Could not open file " + filePath);

        emit wasError("Could not open file " + filePath);

        return QByteArray();
    }

    QString crlf = "\r\n";

    dataToSend.append(QString("--").toAscii());
    dataToSend.append(boundary.toAscii());
    dataToSend.append(crlf.toAscii());

    dataToSend.append(QString("Content-Disposition: form-data; name=\"fileupload\"; filename=\"%1\"").arg(fileInfo.fileName()).toAscii());
    dataToSend.append(crlf.toAscii());
    dataToSend.append(QString("Content-Type: image/%1").arg(getMimeType(fileInfo.suffix().toLower())).toAscii());

    dataToSend.append(crlf.toAscii());
    dataToSend.append(crlf.toAscii());

    dataToSend.append(fileData);

    dataToSend.append(crlf.toAscii());
    dataToSend.append(QString("--").toAscii());
    dataToSend.append(boundary.toAscii());
    dataToSend.append(QString("--").toAscii());
    dataToSend.append(crlf.toAscii());

    return dataToSend;
}

void ImageShackImageUploader::replyFinished(QNetworkReply *reply) {
    if(reply->error() != QNetworkReply::NoError) {
        log->warningMsg(reply->errorString());

        emit wasError(reply->errorString());

        loop.exit();

        return;
    }

    QString replyString = reply->readAll();
    log->debugMsg("Server reply: " + replyString);

    int linkStartPosition = replyString.indexOf("<image_link>");
    int linkStopPosition = replyString.indexOf("</image_link>");
    int size = QString("<image_link>").length();
    
    QString resultUrlStr = replyString.mid(linkStartPosition + size, linkStopPosition - linkStartPosition - size);

    log->debugMsg("Result url : " + resultUrlStr);

    if(resultUrlStr.size() == 0 || linkStartPosition == -1 || linkStopPosition == -1) {
        log->warningMsg("Could not parse image url from reply");

        emit wasError("Could not parse image url from reply");

        loop.exit();

        return;
    }

    this->resultUrl = resultUrlStr;

    loop.exit();
}

void ImageShackImageUploader::slotError(QNetworkReply::NetworkError error) {
    if(error != QNetworkReply::NoError) {
        log->warningMsg("Connection error");

        wasErrors = true;

        emit wasError("Connection error");

        loop.exit();
    }
}
